home *** CD-ROM | disk | FTP | other *** search
/ Merciful 5 / Merciful - Disc 5.iso / software / p / pcqpascalv1.2d.lha / Examples / SmallCom.p < prev    next >
Encoding:
Text File  |  1991-08-02  |  10.3 KB  |  469 lines

  1. Program SmallCom;
  2.  
  3. {
  4.     This program is a simplistic terminal program, which has
  5. basically no features, but works reasonably well.  It is an ANSI
  6. compatible terminal to the extent that the console.device is - it
  7. simply passes incoming data, from the keyboard or the serial device,
  8. to the console device.
  9.  
  10.     To gain some control over the program, you might want to take a look
  11. at the translated characters (after the call to DeadKeyConvert), and
  12. process a few (function keys, for example) instead of sending them on
  13. to the console.device.
  14. }
  15.  
  16. {$I "Include:Exec/Interrupts.i"}
  17. {$I "Include:Exec/Libraries.i"}
  18. {$I "Include:Exec/Ports.i"}
  19. {$I "Include:Exec/IO.i"}
  20. {$I "Include:Exec/Devices.i"}
  21. {$I "Include:Devices/Console.i"}
  22. {$I "Include:Utils/IOUtils.i"}
  23. {$I "Include:Utils/ConsoleIO.i"}
  24. {$I "Include:Intuition/Intuition.i"}
  25. {$I "Include:Devices/InputEvent.i"}
  26. {$I "Include:Utils/DeadKeyConvert.i"}
  27. {$I "Include:Utils/BuildMenu.i"}
  28. {$I "Include:Devices/Serial.i"}
  29. {$I "Include:Exec/Memory.i"}
  30. {$I "Include:Utils/StringLib.i"}
  31.  
  32.  
  33. Type
  34.     ParityType = (no_parity, even_parity, odd_parity);
  35.  
  36. Const
  37.     w        : WindowPtr = Nil;
  38.     SerialWrite    : IOExtSerPtr = Nil;
  39.     SerialRead    : IOExtSerPtr = Nil;
  40.     ConsoleWrite : IOStdReqPtr = Nil;
  41.  
  42.     WritingConsole    : Boolean = False;
  43.     WritingSerial    : Boolean = False;
  44.  
  45.     SerialSendBuffer    : String = Nil;
  46.     ConsoleSendBuffer    : String = Nil;
  47.     SerialReceiveBuffer : String = Nil;
  48.     TranslateBuffer    : String = Nil;
  49.  
  50.     BaudRate    : Integer = 2400;
  51.     DataBits    : Byte = 8;
  52.     Parity    : ParityType = no_parity;
  53.     StopBits    : Byte = 1;
  54.     HalfDuplex    : Boolean = False;
  55.  
  56.     QuitStopDie    : Boolean = False;
  57.  
  58.     BaudRates    : Array [0..7] of Integer = (300, 1200, 2400,
  59.                          4800, 9600, 19200,
  60.                          38400,115200);
  61.  
  62. var
  63.     IMessage    : IntuiMessage;
  64.     Msg        : MessagePtr;
  65.     TitleBuffer : Array [0..79] of Char;
  66.  
  67. Procedure MakeWindowTitle;
  68. var
  69.     TitlePtr : String;
  70.     NumBuff  : Array [0..79] of Char;
  71.     Error    : Integer;
  72. begin
  73.     TitlePtr := Adr(TitleBuffer);
  74.     strcpy(TitlePtr, "SmallCom     ");
  75.     Error := IntToStr(Adr(NumBuff), BaudRate);
  76.     strcat(TitlePtr, Adr(NumBuff));
  77.     NumBuff[0] := ' ';
  78.     NumBuff[1] := Chr(DataBits + 48);
  79.     case Parity of
  80.       no_parity    : NumBuff[2] := 'N';
  81.       even_parity : NumBuff[2] := 'E';
  82.       odd_parity  : NumBuff[2] := 'O';
  83.     end;
  84.     NumBuff[3] := Chr(StopBits + 48);
  85.     NumBuff[4] := '\0';
  86.     strcat(TitlePtr, Adr(NumBuff));
  87.     SetWindowTitles(w, TitlePtr, Nil);
  88. end;
  89.  
  90. Function OpenTheWindow : Boolean;
  91. var
  92.     nw : NewWindowPtr;
  93. begin
  94.     new(nw);
  95.     with nw^ do begin
  96.     LeftEdge := 0;
  97.     TopEdge := 0;
  98.     Width := 320;
  99.     Height := 200;
  100.  
  101.     DetailPen := -1;
  102.     BlockPen  := -1;
  103.     IDCMPFlags := RAWKEY_f + MENUPICK_f + CLOSEWINDOW_f;
  104.     Flags := SMART_REFRESH + ACTIVATE + WINDOWSIZING + WINDOWDRAG +
  105.             WINDOWDEPTH + WINDOWCLOSE + SIZEBBOTTOM;
  106.     FirstGadget := Nil;
  107.     CheckMark := Nil;
  108.     Title := "";
  109.     Screen := Nil;
  110.     BitMap := Nil;
  111.     MinWidth := 0;
  112.     MaxWidth := -1;
  113.     MinHeight := 0;
  114.     MaxHeight := -1;
  115.     WType := WBENCHSCREEN_f;
  116.     end;
  117.  
  118.     w := OpenWindow(nw);
  119.     dispose(nw);
  120.     OpenTheWindow := w <> nil;
  121. end;
  122.  
  123. Procedure AddTheMenus;
  124. begin
  125.     InitializeMenu(w);
  126.     NewMenu("Project");
  127.     NewItem("Quit",'Q');
  128.     NewMenu("Serial");
  129.  
  130.     NewItem("Baud Rate",'\0');
  131.     NewSubItem("   300", '1');
  132.     NewSubItem("  1200", '2');
  133.     NewSubItem("  2400", '3');
  134.     NewSubItem("  4800", '4');
  135.     NewSubItem("  9600", '5');
  136.     NewSubItem(" 19200", '6');
  137.     NewSubItem(" 38400", '7');
  138.     NewSubItem("115200", '8');
  139.  
  140.     NewItem("Data Size", '\0');
  141.     NewSubItem("7N2", '\0');
  142.     NewSubItem("7E1", '\0');
  143.     NewSubItem("7O1", '\0');
  144.     NewSubItem("8N1", '\0');
  145.  
  146.     NewItem("Duplex   ", '\0');
  147.     NewSubItem("Half", 'H');
  148.     NewSubItem("Full", 'F');
  149.  
  150.     AttachMenu;
  151. end;
  152.  
  153.  
  154. Function CreateExtIO(ioReplyPort : MsgPortPtr; Size : Integer) : Address;
  155. var
  156.     Request : IOStdReqPtr;
  157. begin
  158.     if ioReplyPort = Nil then
  159.     CreateExtIO := Nil;
  160.  
  161.     Request := AllocMem(Size, MEMF_CLEAR + MEMF_PUBLIC);
  162.     if Request = Nil then
  163.     CreateExtIO := Nil;
  164.  
  165.     with Request^.io_Message.mn_Node do begin
  166.     ln_Type := NTMessage;
  167.     ln_Pri := 0;
  168.     end;
  169.     Request^.io_Message.mn_ReplyPort := ioReplyPort;
  170.     CreateExtIO := Request;
  171. end;
  172.  
  173.  
  174. Procedure DeleteExtIO(Request : Address; Size : Integer);
  175. var
  176.     Req : IOStdReqPtr;
  177. begin
  178.     Req := Request;
  179.     with Req^ do begin
  180.     io_Message.mn_Node.ln_Type := NodeType($FF);
  181.     io_Device := Address(-1);
  182.     io_Unit := Address(-1);
  183.     end;
  184.     FreeMem(Request, Size);
  185. end;
  186.  
  187.  
  188. Procedure Die;
  189. var
  190.     Error : Integer;
  191. begin
  192.     if SerialWrite <> Nil then begin
  193.     if CheckIO(SerialRead) = Nil then begin
  194.         Error := AbortIO(SerialRead);
  195.         Error := WaitIO(SerialRead);
  196.     end;
  197.     CloseDevice(SerialWrite);
  198.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  199.     if SerialRead <> Nil then
  200.         DeleteExtIO(SerialRead, SizeOf(IOExtSer));
  201.     end;
  202.  
  203.     if ConsoleWrite <> Nil then begin
  204.     CloseDevice(ConsoleWrite);
  205.     DeleteStdIO(ConsoleWrite);
  206.     end;
  207.     if w <> Nil then begin
  208.     DetachMenu;
  209.     DisposeMenu;
  210.     Forbid;
  211.     while GetMsg(w^.UserPort) <> Nil do;
  212.     Permit;
  213.     CloseWindow(w);
  214.     end;
  215.     Exit(0);
  216. end;
  217.  
  218. Procedure SendSerial(IO : IOExtSerPtr; Data : Address; Size : Integer);
  219. var
  220.     Error : Short;
  221. begin
  222.     with IO^.IOSer do begin
  223.     io_Data := Data;
  224.     io_Length := Size;
  225.     io_Command := CMD_WRITE;
  226.     end;
  227.     Error := DoIO(IO);
  228. end;
  229.  
  230. Procedure QueueSerialRead;
  231. var
  232.     Waiting : Integer;
  233. begin
  234.     with SerialRead^.IOSer do begin
  235.     io_Command := SDCMD_QUERY;
  236.     Waiting := DoIO(SerialRead);
  237.     Waiting := io_Actual;
  238.     if Waiting = 0 then
  239.         Waiting := 1
  240.     else if Waiting > 80 then
  241.         Waiting := 80;
  242.     io_Length := Waiting;
  243.     io_Command := CMD_READ;
  244.     io_Data := SerialReceiveBuffer;
  245.     end;
  246.     SendIO(SerialRead);
  247. end;
  248.  
  249.  
  250. Procedure SetSerialParams;
  251. var
  252.     Error : Short;
  253. begin
  254.     with SerialWrite^ do begin
  255.     io_ReadLen    := DataBits;
  256.     io_BrkTime    := 750000;
  257.     io_Baud        := BaudRate;
  258.     io_WriteLen    := DataBits;
  259.     io_StopBits    := StopBits;
  260.     io_RBufLen    := 4000;
  261.     io_TermArray.TermArray0 := $51040303;
  262.     io_TermArray.TermArray1 := $03030303;
  263.     io_CtlChar    := SER_DEFAULT_CTLCHAR;
  264.     case parity of
  265.       no_parity    : io_SerFlags := 0;
  266.       even_parity    : io_SerFlags := SERF_PARTY_ON;
  267.       odd_parity    : io_SerFlags := SERF_PARTY_ON + SERF_PARTY_ODD;
  268.     end;
  269.     IOSer.io_Command := SDCMD_SETPARAMS;
  270.     end;
  271.     if CheckIO(SerialRead) = Nil then begin
  272.     Error := AbortIO(SerialRead);
  273.     Error := WaitIO(SerialRead);
  274.     end;
  275.     Error := DoIO(SerialWrite);
  276.     if Error <> 0 then
  277.     ConWrite(ConsoleWrite, "\nError setting serial port paramters\n",37);
  278.     QueueSerialRead;
  279.     MakeWindowTitle;
  280. end;
  281.  
  282.  
  283. Function OpenSerialDevice : Boolean;
  284. var
  285.     Error : Short;
  286. begin
  287.     SerialWrite := CreateExtIO(w^.UserPort, SizeOf(IOExtSer));
  288.     if SerialWrite = Nil then
  289.     OpenSerialDevice := False;
  290.     SerialRead := CreateExtIO(w^.UserPort, SizeOf(IOExtSer));
  291.     if SerialWrite = Nil then begin
  292.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  293.     SerialWrite := Nil;
  294.     OpenSerialDevice := False;
  295.     end;
  296.  
  297.     with SerialWrite^ do begin
  298.     io_ReadLen    := DataBits;
  299.     io_BrkTime    := 750000;
  300.     io_Baud        := BaudRate;
  301.     io_WriteLen    := DataBits;
  302.     io_StopBits    := StopBits;
  303.     io_RBufLen    := 4000;
  304.     io_SerFlags    := 0;
  305.     io_SerFlags    := 0;
  306.     end;
  307.  
  308.     Error := OpenDevice("serial.device", 0, SerialWrite, 0);
  309.  
  310.     if Error = 0 then begin
  311.     SerialRead^ := SerialWrite^;
  312.     QueueSerialRead;
  313.     SetSerialParams;
  314.     OpenSerialDevice := True;
  315.     end else begin
  316.     DeleteExtIO(SerialWrite, SizeOf(IOExtSer));
  317.     DeleteExtIO(SerialRead, SizeOf(IOExtSer));
  318.     SerialWrite := Nil;
  319.     OpenSerialDevice := False;
  320.     end;
  321. end;
  322.  
  323.  
  324. Function OpenConsoleDevice : Boolean;
  325. var
  326.     Error : Short;
  327. begin
  328.     ConsoleWrite := CreateStdIO(w^.UserPort);
  329.     if ConsoleWrite = Nil then
  330.     OpenConsoleDevice := False;
  331.  
  332.     with ConsoleWrite^ do begin
  333.     io_Data := w;
  334.     io_Length := SizeOf(Window);
  335.     end;
  336.  
  337.     Error := OpenDevice("console.device", 0, ConsoleWrite, 0);
  338.     if Error = 0 then
  339.     ConsoleBase := ConsoleWrite^.io_Device
  340.     else
  341.     DeleteStdIO(ConsoleWrite);
  342.     OpenConsoleDevice := Error = 0;
  343. end;
  344.  
  345.  
  346. Procedure OpenEverything;
  347. begin
  348.     SerialSendBuffer    := AllocString(80);
  349.     ConsoleSendBuffer    := AllocString(80);
  350.     SerialReceiveBuffer := AllocString(80);
  351.     TranslateBuffer    := AllocString(80);
  352.     
  353.     if not OpenTheWindow then
  354.     Die;
  355.  
  356.     AddTheMenus;
  357.  
  358.     if not OpenConsoleDevice then
  359.     Die;
  360.  
  361.     if not OpenSerialDevice then
  362.     Die;
  363. end;
  364.  
  365.  
  366. Procedure ProcessIntuitionMsg;
  367. var
  368.     IMessage    : IntuiMessage;
  369.     IPtr    : IntuiMessagePtr;
  370.  
  371.     Procedure ProcessMenu;
  372.     var
  373.     MenuNumber    : Short;
  374.     ItemNumber    : Short;
  375.     SubItemNumber    : Short;
  376.     begin
  377.     if IMessage.Code = MENUNULL then
  378.         return;
  379.  
  380.     MenuNumber := MenuNum(IMessage.Code);
  381.     ItemNumber := ItemNum(IMessage.Code);
  382.     SubItemNumber := SubNum(IMessage.Code);
  383.  
  384.     case MenuNumber of
  385.       0 : if ItemNumber = 0 then
  386.          QuitStopDie := True;
  387.       1 : begin
  388.           case ItemNumber of
  389.             0 : BaudRate := BaudRates[SubItemNumber];
  390.             1 : case SubItemNumber of
  391.               0 : begin
  392.                   DataBits := 7;
  393.                   Parity   := no_parity;
  394.                   StopBits := 2;
  395.                   end;
  396.               1 : begin
  397.                   DataBits := 7;
  398.                   Parity   := even_parity;
  399.                   StopBits := 1;
  400.                   end;
  401.               2 : begin
  402.                   DataBits := 7;
  403.                   Parity   := odd_parity;
  404.                   StopBits := 1;
  405.                   end;
  406.               3 : begin
  407.                   DataBits := 8;
  408.                   Parity   := no_parity;
  409.                   StopBits := 1;
  410.                   end;
  411.             end;
  412.             2 : HalfDuplex := SubItemNumber = 0;
  413.           end;
  414.           if ItemNumber < 2 then
  415.               SetSerialParams;
  416.           end;
  417.     end;
  418.     end;
  419.  
  420.  
  421.     Procedure ProcessKeypress;
  422.     var
  423.     Length    : Short;
  424.     Buffer    : Array [0..79] of Char;
  425.     begin
  426.     if IMessage.Code < 128 then begin
  427.         Length := DeadKeyConvert(Adr(IMessage), TranslateBuffer, 79, Nil);
  428.         if Length > 0 then begin
  429.         if HalfDuplex then
  430.             ConWrite(ConsoleWrite, TranslateBuffer, Length);
  431.         SendSerial(SerialWrite, TranslateBuffer, Length);
  432.         end;
  433.     end;
  434.     end;
  435.  
  436. begin
  437.     IPtr := IntuiMessagePtr(Msg);
  438.     IMessage := IPtr^;
  439.     ReplyMsg(Msg);
  440.  
  441.     case IMessage.Class of
  442.       MENUPICK_f : ProcessMenu;
  443.       RAWKEY_f   : ProcessKeypress;
  444.       CLOSEWINDOW_f : QuitStopDie := True;
  445.     end;
  446. end;
  447.  
  448. Procedure ProcessSerialInput;
  449. begin
  450.     with SerialRead^.IOSer do begin
  451.     if io_Actual > 0 then
  452.         ConWrite(ConsoleWrite, SerialReceiveBuffer, io_Actual);
  453.     end;
  454.     QueueSerialRead;
  455. end;
  456.  
  457. begin
  458.     OpenEverything;
  459.     repeat
  460.     Msg := WaitPort(w^.UserPort);
  461.     Msg := GetMsg(w^.UserPort);
  462.     if Msg = MessagePtr(SerialRead) then
  463.         ProcessSerialInput
  464.     else
  465.         ProcessIntuitionMsg;
  466.     until QuitStopDie;
  467.     Die;
  468. end.
  469.